from aiogram_dialog import DialogManager
from fluentogram import TranslatorRunner
from sqlalchemy.ext.asyncio import AsyncSession

from src.application.category.service import CategoryService
from src.application.order.enums import OrderPeriod, OrderType
from src.application.order.service import OrderService
from src.application.server.enums import ServerPrivacy, ServerType
from src.infrastructure.date_helpers import get_date_time
from src.infrastructure.db.services.countries import get_country
from src.infrastructure.db.services.providers import get_provider
from src.infrastructure.db.services.proxy import get_proxy
from src.infrastructure.db.services.sites import get_site
from src.infrastructure.utils.helpers import get_expiring_on, get_price_by_category


async def all_orders_getter(dialog_manager: DialogManager, **kwargs):
    """Получаем все заказы"""

    order_service: OrderService = dialog_manager.middleware_data.get("order_service")

    orders = await order_service.get_orders()

    return {"orders": orders}


async def order_info_getter(dialog_manager: DialogManager, **kwargs):
    """Получаем информацию о заказе"""

    locale: TranslatorRunner = dialog_manager.middleware_data.get("locale")
    user_id: int = dialog_manager.middleware_data["event_from_user"].id
    order_service: OrderService = dialog_manager.middleware_data.get("order_service")

    if dialog_manager.start_data and dialog_manager.start_data.get("order_id"):
        order_id: int = dialog_manager.start_data.get("order_id")
        order = await order_service.get_order_by_id(order_id)
        dialog_manager.dialog_data["order_id"] = order_id
    else:
        order = await order_service.get_user_subscription_order(user_id)
        order_id: int = order.id
        dialog_manager.dialog_data["order_id"] = order.id
    allowed_ip = await get_allowed_ip_by_order(order.user.telegram_id, order_id)  # TODO Вынести в юзкейс

    if order.auto_renew:
        dialog_manager.dialog().find("autorenew").default = True
    else:
        dialog_manager.dialog().find("autorenew").default = False

    category = None
    country = None
    provider = None

    if locale.translators[0].locale == "ru":
        if order.country:
            country = order.country.name
        if order.category:
            category = order.category.name
        if order.provider:
            provider = order.provider.name
    else:
        if order.country:
            country = order.country.name_eng
        if order.category:
            category = order.category.name_eng
        if order.provider:
            provider = order.provider.name_eng

    if order.expiring_on:
        expiring_on = order.expiring_on
    else:
        expiring_on = ""

    site = order.site.name if order.site else None

    server_time = get_date_time()
    status = locale.get(order.status.value)
    order_period = locale.get(order.period.value)

    data = {
        "order_id": order_id,
        "period": order.period,
        "order_period": order_period,
        "status": status,
        "order_type": order.type.value,
        "order_status": order.status.value,
        "proxies_amount": len(order.proxies),
        "package_price": order.summ,
        "complete_price": order.summ_total,
        "created_at": order.was_created,
        "expiring_on": expiring_on,
        "server_time": server_time,
        "country": country,
        "category": category,
        "provider": provider,
        "site": site,
    }

    if order.proxies:
        proxy = await get_proxy(order.proxies[0].id)
        proxy_type = proxy.server.proxy_type
        proxy_privacy = proxy.server.proxy_privacy
        data.update(
            {
                "proxy_type_translated": locale.get(proxy_type.value),
                "proxy_type": proxy_type.value,
                "proxy_privacy": proxy_privacy.value,
                "proxy_privacy_translated": locale.get(proxy_privacy.value),
                "one_proxy_price": round(order.summ / len(order.proxies), 2),
                "authorization_type": locale.get(proxy.authorization_type),
                "authorization_ip": allowed_ip.ip_address if allowed_ip else None,
            }
        )

        if proxy_type == ServerType.mobile and proxy_privacy == ServerPrivacy.private:
            data.update(
                {
                    "rotation_period": proxy.reload_period,
                    "rotation_type": locale.get(proxy.reload_type),
                }
            )

    return data


async def extend_summary_getter(dialog_manager: DialogManager, **kwargs):
    order_id: int = dialog_manager.dialog_data.get("order_id")
    order_service: OrderService = dialog_manager.middleware_data.get("order_service")
    period: str = dialog_manager.dialog_data.get("period")
    order = await order_service.get_order_by_id(order_id)

    extended_expiring_on = await get_expiring_on(order.expiring_on, getattr(OrderPeriod, period))
    if order.order_type == OrderType.proxy:
        extend_price = await get_price_by_category(getattr(OrderPeriod, period), order.category, len(order.proxies))
    else:
        extend_price = order.category.price_1m  # TODO Переделать этот момент

    dialog_manager.dialog_data["extend_price"] = extend_price

    return {
        "order_id": order_id,
        "expiring_on": order.expiring_on,
        "extended_expiring_on": extended_expiring_on,
        "extend_price": extend_price,
    }


async def order_summary_getter(db_session: AsyncSession, dialog_manager: DialogManager, **kwargs):
    """Рассчитываем сумму заказа"""

    locale: TranslatorRunner = dialog_manager.middleware_data.get("locale")
    category_service: CategoryService = dialog_manager.middleware_data.get("category_service")

    proxy_type: str = dialog_manager.dialog_data.get("proxy_type")
    proxy_privacy: str = dialog_manager.dialog_data.get("proxy_privacy")

    country_id: int = dialog_manager.dialog_data.get("country_id")
    country = await get_country(db_session, country_id)

    provider_id: int = dialog_manager.dialog_data.get("provider_id")
    provider = await get_provider(db_session, provider_id)

    category_id: int = dialog_manager.dialog_data.get("category_id")

    if category_id:
        category = await category_service.get_category_by_id(category_id)
    else:
        category = await category_service.get_category_for_private(country_id, provider_id)

    site_id: int = dialog_manager.dialog_data.get("site_id")

    site = None
    if site_id:
        site = await get_site(db_session, site_id)

    selected_amount: int = dialog_manager.dialog_data.get("selected_amount")
    period: str = dialog_manager.dialog_data.get("period")

    if dialog_manager.start_data and dialog_manager.start_data.get("for_test"):
        order_summ = 0
    else:
        order_summ = await get_price_by_category(period, category, selected_amount)

    period = locale.get(period)
    proxy_type = locale.get(proxy_type)
    proxy_privacy = locale.get(proxy_privacy)

    if locale.translators[0].locale == "ru":
        country = country.name if country else None
        category = category.name
        provider = provider.name if provider else None
    else:
        country = country.name_eng if country else None
        category = category.name_eng
        provider = provider.name_eng if provider else None

    dialog_manager.dialog_data["order_summ"] = order_summ

    return {
        "proxy_type": proxy_type,
        "proxy_privacy": proxy_privacy,
        "country": country,
        "provider": provider,
        "category": category,
        "site": site,
        "selected_amount": selected_amount,
        "period": period,
        "order_summ": order_summ,
    }


async def subscription_summary_getter(db_session: AsyncSession, dialog_manager: DialogManager, **kwargs):
    """Рассчитываем сумму заказа подписки"""

    locale: TranslatorRunner = dialog_manager.middleware_data.get("locale")
    category_service: CategoryService = dialog_manager.middleware_data.get("category_service")

    category = await category_service.get_category_by_name("Подписка")
    period: str = dialog_manager.dialog_data.get("subscription_period")

    subscription_summ = await get_price_by_category(period, category, 1)
    dialog_manager.dialog_data["subscription_summ"] = subscription_summ

    return {
        "subscription_summ": subscription_summ,
        "period": locale.get(period),
    }


async def vpn_summary_getter(db_session: AsyncSession, dialog_manager: DialogManager, **kwargs):
    locale: TranslatorRunner = dialog_manager.middleware_data.get("locale")
    category_service: CategoryService = dialog_manager.middleware_data.get("category_service")

    category = await category_service.get_category_by_name("VPN")

    vpn_summ = await get_price_by_category(OrderPeriod.one_month, category, 1)
    dialog_manager.dialog_data["vpn_summ"] = vpn_summ

    return {
        "vpn_summ": vpn_summ,
        "period": locale.get(OrderPeriod.one_month.value),
        "service_name": locale.get("vpn-service"),
    }


async def vpn_router_summary_getter(dialog_manager: DialogManager, **kwargs):
    locale: TranslatorRunner = dialog_manager.middleware_data.get("locale")
    category_service: CategoryService = dialog_manager.middleware_data.get("category_service")
    category = await category_service.get_category_by_name("VPN Router")

    vpn_summ = await get_price_by_category(OrderPeriod.one_month, category, 1)
    dialog_manager.dialog_data["vpn_summ"] = vpn_summ

    return {"vpn_summ": vpn_summ, "service_name": locale.get("vpn-router-service")}


async def user_subscription_getter(dialog_manager: DialogManager, **kwargs):
    user_id: int = dialog_manager.middleware_data.get("event_from_user").id
    order_service: OrderService = dialog_manager.middleware_data.get("order_service")

    subscription_order = await order_service.get_user_subscription_order(user_id)
    if subscription_order:
        dialog_manager.dialog_data["order_id"] = subscription_order.id

    return {
        "subscription_order": subscription_order,
    }
